package com.gitee.wsl.common.ui.ext.color

import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.compositeOver
import androidx.compose.ui.graphics.luminance
import kotlin.math.max
import kotlin.math.min

/** Returns the brightness of this color in [0.0-1.0] range ignoring the alpha. */
val Color.colorBrightness: Float
    get() = getColorBrightness(this.red, this.green, this.blue)


/** Returns the brightness of the specified color values in [0.0-1.0] range. */
fun getColorBrightness(r: Float, g: Float, b: Float): Float {
    // See https://en.wikipedia.org/wiki/Relative_luminance
    return (2126.0f * r + 7152.0f * g + 722.0f * b) / 10000.0f
}

fun Color.withBrightness(brightnessSource: Color): Color {
    val hsbvalsOrig = RGBtoHSB(this)
    val hsbvalsBrightnessSrc = RGBtoHSB(brightnessSource)
    return HSBtoRGB(
        floatArrayOf(
            hsbvalsOrig[0], hsbvalsOrig[1],
            (hsbvalsBrightnessSrc[2] + hsbvalsOrig[2]) / 2.0f
        )
    ).byAlpha(this.alpha)
}

/**
 * 颜色变量
 * @param brightnessFactor 因子, < 1: 变暗, > 1: 变亮
 */
fun Color.withBrightness(brightnessFactor: Float): Color {
    val hsbvalsOrig = RGBtoHSB(this)

    // Brightness factor is in -1.0...1.0 range. Negative values are treated as darkening
    // and positive values are treated as brightening - leaving the hue and saturation intact
    val newBrightness =
        if (brightnessFactor > 0.0f) hsbvalsOrig[2] + (1.0f - hsbvalsOrig[2]) * brightnessFactor else hsbvalsOrig[2] + hsbvalsOrig[2] * brightnessFactor
    return HSBtoRGB(
        floatArrayOf(hsbvalsOrig[0], hsbvalsOrig[1], newBrightness)
    ).byAlpha(this.alpha)
}


fun Color.contrastAgainst(background: Color): Float {
    val fg = if (alpha < 1f) compositeOver(background) else this
    val fgLuminance = fg.luminance() + 0.05f
    val bgLuminance = background.luminance() + 0.05f

    return max(fgLuminance, bgLuminance) / min(fgLuminance, bgLuminance)
}
